package com.ionehe.group.common.uaa.ex.domain.service.impl;

import cn.hutool.http.HttpStatus;
import com.google.common.base.Throwables;
import com.ionehe.group.common.io.Response;
import com.ionehe.group.common.uaa.ex.domain.service.UaaCommonService;
import com.ionehe.group.common.uaa.ex.domain.service.UserReadService;
import com.ionehe.group.common.uaa.ex.dto.CustomerInfoDTO;
import com.ionehe.group.common.uaa.ex.dto.LoginInfoDTO;
import com.ionehe.group.common.uaa.ex.dto.UserDetailDTO;
import com.ionehe.group.common.uaa.ex.dto.UserInfoDTO;
import com.ionehe.group.common.uaa.ex.enums.ErrorMessages;
import com.ionehe.group.common.uaa.ex.utils.RedisUtils;
import com.ionehe.group.common.user.c.sdk.uaa.utils.JwtTokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.Random;

/**
 * Copyright (c) 2021 ionehe.com
 * Date: 2021/10/15
 * Time: 11:01 上午
 *
 * @author 2021年 <a href="mailto:a@ionehe.com">秀</a>
 * 【uaa common service】
 */
@Service
@Slf4j
public class UaaCommonServiceImpl implements UaaCommonService {
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private UserReadService userReadService;
    @Autowired
    private RedisUtils redisUtils;
    @Value("${redis.database:base}")
    private String redisDatabase;
    @Value("${redis.key.authCode:uaa:authCode}")
    private String redisKeyAuthCode;
    @Value("${redis.expire.authCode:300}")
    private Long redisExpireAuthCode;
    @Value("${redis.expire.common:86400}")
    private Long redisExpire;
    @Value("${redis.key.user:uaa:user}")
    private String redisKeyUser;
    @Value("${jwt.tokenLimit:-1}")
    private Integer tokenLimit;

    @Override
    public Response<String> generateAuthCode(String key) {
        try {

            StringBuilder authCode = new StringBuilder();
            Random random = new Random();
            for (int i = 0; i < 4; i++) {
                int code = random.nextInt(10);
                authCode.append(code);
            }
            redisUtils.set(0, generateKey(key), authCode.toString(), redisExpireAuthCode);
            return Response.yes(authCode.toString(), HttpStatus.HTTP_OK, "Access.success.general", null);
        } catch (Exception e) {
            log.error("AdminWriteService[]generateAuthCode[]error! cause:{}", Throwables.getStackTraceAsString(e));
            return Response.no(ErrorMessages.VERIFICATION_CODE_GENERATION_FAIL.getErrCode(),
                    ErrorMessages.VERIFICATION_CODE_GENERATION_FAIL.getErrMsg());
        }
    }

    /**
     * 验证码校验
     *
     * @param key  key
     * @param code 验证码
     */
    @Override
    public Response<Boolean> verificationCodeCheck(String key, String code) {
        if ("8888".equals(code)) {
            return Response.yes(true);
        }

        key = generateKey(key);
        if (!Objects.equals(code, redisUtils.get(0, key))) {
            return Response.no(ErrorMessages.ILLEGAL_VERIFICATION_CODE.toString());
        }

        if (!redisUtils.delete(0, key)) {
            return Response.no(ErrorMessages.VERIFICATION_CODE_CHECK_FAIL.toString());
        }

        return Response.yes(true);
    }

    @Override
    public Response<UserInfoDTO> getUserByToken(String token) {
        log.info("UaaCommonService[]getUserByToken[]token:{}", token);
        String userName = jwtTokenUtil.getUserNameFromToken(token);
        Response<UserDetailDTO> userRes = userReadService.getUserByUsername(userName);
        if (!userRes.success()) {
            return Response.no(userRes.getMessage());
        }

        UserInfoDTO userInfoDTO = userRes.getData().getUserInfoDTO();
        LoginInfoDTO loginInfoDTO = userRes.getData().getLoginInfoDTO();
        CustomerInfoDTO customerInfoDTO = userRes.getData().getCustomerInfoDTO();
        if (customerInfoDTO != null) {
            userInfoDTO.setParentCustomerId(customerInfoDTO.getPid());
            CustomerInfoDTO simpleCustomer = new CustomerInfoDTO();
            simpleCustomer.setId(customerInfoDTO.getId());
            simpleCustomer.setPid(customerInfoDTO.getPid());
            simpleCustomer.setType(customerInfoDTO.getType());
            simpleCustomer.setName(customerInfoDTO.getName());
            userInfoDTO.setCustomerInfo(customerInfoDTO);
        }

        if (Boolean.FALSE.equals(loginInfoDTO.getAlreadyFirstLogin())) {
            // 0 需要修改密码再登陆
            userInfoDTO.setStatus(0);
        }
        return Response.yes(userInfoDTO);
    }

    private String generateKey(String key) {
        return redisDatabase + ":" + redisKeyAuthCode + ":" + key;
    }
}
